import { randomStr } from '@/utils/random'
import type { ObjectDirective } from 'vue'
import { DragDataType } from './DragDataTypes'
import { dropEventCenter } from './dropEventCenter'
import { DROPPABLE_ACCEPTS_TYPE_KEY, DROPPABLE_ID_KEY, IDragData } from './interfaces'

export interface IVDroppableValue<DragData = any> {
    accepts?: DragDataType[]
    drop?: (data: IDragData<DragData>, target?: HTMLElement | null) => void
    enter?: (data: IDragData<DragData>, target?: HTMLElement | null) => void
    leave?: (data: IDragData<DragData>, target?: HTMLElement | null) => void
}

export const vDroppable: ObjectDirective<any, IVDroppableValue> = {
    mounted: (el: HTMLElement, binding) => {
        // 添加id
        const id = randomStr()
        el.dataset[DROPPABLE_ID_KEY] = id
        // 添加accepts
        if (binding.value.accepts) {
            el.dataset[DROPPABLE_ACCEPTS_TYPE_KEY] = binding.value.accepts.join(',')
        }
        // 在事件中心注册事件
        dropEventCenter.on(id, 'enter', binding.value.enter)
        dropEventCenter.on(id, 'leave', binding.value.leave)
        dropEventCenter.on(id, 'drop', binding.value.drop)
    },
    unmounted: (el: HTMLElement, binding) => {
        // 移除id
        delete el.dataset[DROPPABLE_ID_KEY]
        // 移除accepts
        delete el.dataset[DROPPABLE_ACCEPTS_TYPE_KEY]
        // 从事件中心移除事件
        const id = el.dataset[DROPPABLE_ID_KEY]
        if (!id) return
        dropEventCenter.off(id, 'enter', binding.value.enter)
        dropEventCenter.off(id, 'leave', binding.value.leave)
        dropEventCenter.off(id, 'drop', binding.value.drop)
    }
}
